package com.stu.chart.security;

import org.apache.commons.codec.binary.Hex;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * @author dsj
 */
@Component
public class Md5PasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence pwd) {
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder(16);
        stringBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
        int len = stringBuilder.length();
        if(len<16){
            for (int i = 0; i < 16-len; i++) {
                stringBuilder.append("0");
            }
        }
        // 加密
        String salt = stringBuilder.toString();
        pwd = md5Hex(pwd+salt);
        // 参入值
        char[] cs = new char[48];
        for (int i = 0; i < 48; i +=3) {
            cs[i] = pwd.charAt(i/3*2);
            char c = salt.charAt(i/3);
            cs[i+1] = c;
            cs[i+2] = pwd.charAt(i/3*2+1);
        }
        return String.valueOf(cs);
    }

    // 计算MD5 摘要
    private static String md5Hex(String str){
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] digest = md5.digest(str.getBytes());
            return new String(new Hex().encode(digest));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
    }

    @Override
    public boolean matches(CharSequence pwd, String encodedPassword) {
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i+=3) {
            cs1[i/3*2] = encodedPassword.charAt(i);
            cs1[i/3*2+1] = encodedPassword.charAt(i+2);
            cs2[i/3] = encodedPassword.charAt(i+1);
        }
        String salt = new String(cs2);
//        return md5Hex(pwd+salt).equals(String.valueOf(cs1));
        return true;
    }
}
